home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src890906.arc / MAIN.C < prev    next >
C/C++ Source or Header  |  1989-09-07  |  11KB  |  585 lines

  1. /* Main network program - provides both client and server functions */
  2. #define HOSTNAMELEN 32        /* changed from 16 by Bdale 860812 */
  3. #include <stdio.h>
  4. #include <time.h>
  5. #ifdef    __TURBOC__
  6. #include <io.h>
  7. #endif
  8. #ifdef    ANSIPROTO
  9. #include <stdarg.h>
  10. #endif
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "socket.h"
  14. #include "iface.h"
  15. #include "ftpcli.h"
  16. #include "telnet.h"
  17. #include "ax25tnc.h"
  18. #include "remote.h"
  19. #include "session.h"
  20. #include "cmdparse.h"
  21. #include "ax25.h"
  22. #include "kiss.h"
  23. #include "enet.h"
  24. #include "timer.h"
  25. #include "proc.h"
  26. #include "tty.h"
  27. #include "daemon.h"
  28. #include "usock.h"
  29. #include "netrom.h"
  30. #include "ip.h"
  31. #include "tcp.h"
  32. #include "udp.h"
  33. #ifdef    MSDOS
  34. #include "pc.h"
  35. #endif
  36. #include "commands.h"
  37.  
  38. extern struct cmds Cmds[],Startcmds[],Stopcmds[];
  39. extern int32 Heapsize;
  40. extern struct daemon Daemons[];
  41. extern char Version[];
  42. extern char *Startup;    /* File to read startup commands from */
  43. extern int Refuse_echo;
  44. extern int Unix_line_mode;
  45. extern char *Rempass;
  46.  
  47. #ifndef    MSDOS            /* PC uses F-10 key always */
  48. static char Escape = 0x1d;    /* default escape character is ^] */
  49. #endif
  50.  
  51. char Badhost[] = "Unknown host %s\n";
  52. char Hostname[HOSTNAMELEN];    
  53. static char Prompt[] = "net> ";
  54. char Nospace[] = "No space!!\n";    /* Generic malloc fail message */
  55. struct mbuf *Hopper;
  56. static FILE *Logfp;
  57. static struct mbuf *Cmdq;
  58. static struct proc *Cmdpp;
  59. extern struct cmds Attab[];
  60.  
  61. #ifdef    AMIGA
  62. void        /* lattice C on the amiga has some pretty weird ideas */
  63. #else
  64. int
  65. #endif
  66. main(argc,argv)
  67. int argc;
  68. char *argv[];
  69. {
  70.     char *inbuf,*intmp;
  71.     FILE *fp;
  72.     struct daemon *tp;
  73.     struct mbuf *bp;
  74.     int c;
  75.     extern char *optarg;
  76.     extern int optind;
  77.  
  78.     while((c = getopt(argc,argv,"s:d:m:")) != EOF){
  79.         switch(c){
  80.         case 's':    /* Number of sockets */
  81.             Nusock = atoi(optarg);
  82.             break;
  83.         case 'd':    /* Root directory for various files */
  84.             initroot(optarg);
  85.             break;
  86.         case 'm':    /* Heap memory size */
  87.             Heapsize = 1024 * atol(optarg);
  88.             break;
  89.         }
  90.     }
  91.     kinit();
  92.     ioinit(Heapsize);
  93.     sockinit();
  94.     Cmdpp = mainproc("cmdintrp");
  95.     ttysetmode(TTY_ECHO|TTY_EDIT);
  96.     printf("KA9Q Internet Protocol Package, v%s\n",Version);
  97.     printf("Copyright 1989 by Phil Karn, KA9Q\n");
  98.     fflush(stdout);
  99.     Sessions = (struct session *)calloc(Nsessions,sizeof(struct session));
  100.  
  101.     if(optind < argc){
  102.         /* Read startup file named on command line */
  103.         if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
  104.             printf("Can't read config file %s: %s\n",
  105.              argv[optind],sys_errlist[errno]);
  106.     } else {
  107.         fp = fopen(Startup,READ_TEXT);
  108.     }
  109.     if(fp != NULLFILE){
  110.         inbuf = malloc(BUFSIZ);
  111.         intmp = malloc(BUFSIZ);
  112.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  113.             strcpy(intmp,inbuf);
  114.             if(cmdparse(Cmds,inbuf,NULL) != 0){
  115.                 printf("input line: %s",intmp);
  116.             }
  117.         }
  118.         fclose(fp);
  119.         free(inbuf);
  120.         free(intmp);
  121.     }
  122.     /* Start background Daemons */
  123.     for(tp=Daemons;;tp++){
  124.         if(tp->name == NULLCHAR)
  125.             break;
  126.         newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL);
  127.     }
  128.     /* Now loop forever, processing commands */
  129.     for(;;){
  130.         printf(Prompt);
  131.         while(Cmdq == NULLBUF)
  132.             pwait(&Cmdq);
  133.         bp = dequeue(&Cmdq);
  134.         (void)cmdparse(Cmds,bp->data,Current);
  135.         free_p(bp);
  136.         ttysetmode(TTY_ECHO|TTY_EDIT);
  137.     }
  138. }
  139. /* Keyboard input process */
  140. void
  141. keyboard(i,v1,v2)
  142. int i;
  143. void *v1;
  144. void *v2;
  145. {
  146.     int c;
  147.     struct mbuf *bp;
  148.  
  149.     /* Keyboard process loop */
  150.     for(;;){
  151.         c = kbread();
  152. #ifndef    MSDOS
  153.         if(c == Escape && Escape != 0)
  154.             c = -2;
  155. #endif
  156.         /* c == -2 means the command escape key */
  157.         if(c == -2){
  158.             /* Save current tty mode and set cooked */
  159.             if(Current != NULLSESSION && Mode == CONV_MODE){
  160.                 Current->ttymode = ttygetmode();
  161.                 Mode = CMD_MODE;
  162.                 ttysetmode(TTY_ECHO|TTY_EDIT);
  163.                 printf("\n");
  164.                 /* Wake up the command interpreter */
  165.                 alert(Cmdpp,0);
  166.             }
  167.         /* Else give to line editor; if done, queue it */
  168.         } else if((bp = ttydriv(c)) != NULLBUF){
  169.             switch(Mode){
  170.             case CMD_MODE:
  171.                 enqueue(&Cmdq,bp);
  172.                 break;
  173.             case CONV_MODE:
  174.                 enqueue(&Current->input,bp);
  175.                 break;
  176.             }
  177.         }
  178.     }
  179. }
  180. /* Standard commands called from main */
  181. int
  182. dodelete(argc,argv,p)
  183. int argc;
  184. char *argv[];
  185. void *p;
  186. {
  187.     int i;
  188.  
  189.     for(i=1;i < argc; i++){
  190.         if(unlink(argv[i]) == -1){
  191.             printf("Can't delete %s: %s\n",
  192.              argv[i],sys_errlist[errno]);
  193.         }
  194.     }
  195.     return 0;
  196. }
  197. int
  198. dorename(argc,argv,p)
  199. int argc;
  200. char *argv[];
  201. void *p;
  202. {
  203.     if(rename(argv[1],argv[2]) == -1)
  204.         printf("Can't rename: %s\n",sys_errlist[errno]);
  205.     return 0;
  206. }
  207. int
  208. doexit(argc,argv,p)
  209. int argc;
  210. char *argv[];
  211. void *p;
  212. {
  213.     reset_all();
  214.     iostop();
  215.     exit(0);
  216.     return 0;    /* To satisfy lint */
  217. }
  218. int
  219. dohostname(argc,argv,p)
  220. int argc;
  221. char *argv[];
  222. void *p;
  223. {
  224.     if(argc < 2)
  225.         printf("%s\n",Hostname);
  226.     else 
  227.         strncpy(Hostname,argv[1],HOSTNAMELEN);
  228.     return 0;
  229. }
  230. int
  231. dolog(argc,argv,p)
  232. int argc;
  233. char *argv[];
  234. void *p;
  235. {
  236.     static char logname[15];
  237.  
  238.     if(argc < 2){
  239.         if(Logfp)
  240.             printf("Logging to %s\n",logname);
  241.         else
  242.             printf("Logging off\n");
  243.         return 0;
  244.     }
  245.     if(Logfp){
  246.         fclose(Logfp);
  247.         Logfp = NULLFILE;
  248.     }
  249.     if(strcmp(argv[1],"stop") != 0){
  250.         strncpy(logname,argv[1],15);
  251.         Logfp = fopen(logname,APPEND_TEXT);
  252.     }
  253.     return 0;
  254. }
  255. int
  256. dohelp(argc,argv,p)
  257. int argc;
  258. char *argv[];
  259. void *p;
  260. {
  261.     register struct cmds *cmdp;
  262.     int i,j;
  263.  
  264.     printf("Main commands:\n");
  265.     for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i++){
  266.         printf("%s",cmdp->name);
  267.         if((i % 4) == 3)
  268.             printf("\n");
  269.         else {
  270.             for(j=strlen(cmdp->name);j < 16; j++)
  271.                 putchar(' ');
  272.         }
  273.     }
  274.     if((i % 4) != 0)
  275.         printf("\n");
  276.     return 0;
  277. }
  278. int
  279. doecho(argc,argv,p)
  280. int argc;
  281. char *argv[];
  282. void *p;
  283. {
  284.     if(argc < 2){
  285.         if(Refuse_echo)
  286.             printf("Refuse\n");
  287.         else
  288.             printf("Accept\n");
  289.     } else {
  290.         if(argv[1][0] == 'r')
  291.             Refuse_echo = 1;
  292.         else if(argv[1][0] == 'a')
  293.             Refuse_echo = 0;
  294.         else
  295.             return -1;
  296.     }
  297.     return 0;
  298. }
  299. /* set for unix end of line for remote echo mode telnet */
  300. int
  301. doeol(argc,argv,p)
  302. int argc;
  303. char *argv[];
  304. void *p;
  305. {
  306.     if(argc < 2){
  307.         if(Unix_line_mode)
  308.             printf("Unix\n");
  309.         else
  310.             printf("Standard\n");
  311.     } else {
  312.         if(strcmp(argv[1],"unix") == 0)
  313.             Unix_line_mode = 1;
  314.         else if(strcmp(argv[1],"standard") == 0)
  315.             Unix_line_mode = 0;
  316.         else {
  317.             return -1;
  318.         }
  319.     }
  320.     return 0;
  321. }
  322. /* Attach an interface
  323.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  324.  */
  325. int
  326. doattach(argc,argv,p)
  327. int argc;
  328. char *argv[];
  329. void *p;
  330. {
  331.     return subcmd(Attab,argc,argv,p);
  332. }
  333. /* Manipulate I/O device parameters */
  334. int
  335. doparam(argc,argv,p)
  336. int argc;
  337. char *argv[];
  338. void *p;
  339. {
  340.     register struct iface *ifp;
  341.  
  342.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  343.         if(strcmp(argv[1],ifp->name) == 0)
  344.             break;
  345.     }
  346.     if(ifp == NULLIF){
  347.         printf("Interface \"%s\" unknown\n",argv[1]);
  348.         return 1;
  349.     }
  350.     if(ifp->ioctl == NULLFP){
  351.         printf("Not supported\n");
  352.         return 1;
  353.     }
  354.     /* Pass rest of args to device-specific code */
  355.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  356. }
  357.  
  358. /* Display or set IP interface control flags */
  359. int
  360. domode(argc,argv,p)
  361. int argc;
  362. char *argv[];
  363. void *p;
  364. {
  365.     register struct iface *ifp;
  366.  
  367.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  368.         if(strcmp(argv[1],ifp->name) == 0)
  369.             break;
  370.     }
  371.     if(ifp == NULLIF){
  372.         printf("Interface \"%s\" unknown\n",argv[1]);
  373.         return 1;
  374.     }
  375.     if(argc < 3){
  376.         printf("%s: %s\n",ifp->name,
  377.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  378.         return 0;
  379.     }
  380.     switch(argv[2][0]){
  381.     case 'v':
  382.     case 'c':
  383.     case 'V':
  384.     case 'C':
  385.         ifp->flags = CONNECT_MODE;
  386.         break;
  387.     case 'd':
  388.     case 'D':
  389.         ifp->flags = DATAGRAM_MODE;
  390.         break;
  391.     default:
  392.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  393.         return 1;
  394.     }
  395.     return 0;
  396. }
  397.  
  398. #ifndef    MSDOS
  399. static int
  400. doescape(argc,argv,p)
  401. int argc;
  402. char *argv[];
  403. void *p;
  404. {
  405.     if(argc < 2)
  406.         printf("0x%x\n",Escape);
  407.     else 
  408.         Escape = *argv[1];
  409.     return 0;
  410. }
  411. #endif    MSDOS
  412. /* Generate system command packet. Synopsis:
  413.  * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
  414.  */
  415. int
  416. doremote(argc,argv,p)
  417. int argc;
  418. char *argv[];
  419. void *p;
  420. {
  421.     struct sockaddr_in fsock;
  422.     int s,c;
  423.     char *data,x;
  424.     extern int errno;
  425.     extern char *optarg;
  426.     extern int optind;
  427.     int16 port,len;
  428.     char *key = NULLCHAR;
  429.     int klen;
  430.     int32 addr = 0;
  431.     char *cmd,*host;
  432.  
  433.     port = IPPORT_REMOTE;    /* Set default */
  434.     optind = 1;        /* reinit getopt() */
  435.     while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
  436.         switch(c){
  437.         case 'a':
  438.             addr = resolve(optarg);
  439.             break;
  440.         case 'p':
  441.             port = atoi(optarg);
  442.             break;
  443.         case 'k':
  444.             key = optarg;
  445.             klen = strlen(key);
  446.             break;
  447.         case 's':
  448.             Rempass = strdup(optarg);
  449.             return 0;    /* Only set local password */
  450.         }
  451.     }
  452.     if(optind > argc - 2){
  453.         printf("Insufficient args\n");
  454.         return -1;
  455.     }
  456.     host = argv[optind++];
  457.     cmd = argv[optind];
  458.     if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  459.         printf("socket failed\n");
  460.         return 1;
  461.     }
  462.     len = 1;
  463.     /* Did the user include a password or kickme target? */
  464.     if(addr != 0)
  465.         len += sizeof(int32);
  466.  
  467.     if(key != NULLCHAR)
  468.         len += klen;
  469.  
  470.     if(len == 1)
  471.         data = &x;
  472.     else
  473.         data = malloc(len);
  474.  
  475.     fsock.sin_family = AF_INET;
  476.     fsock.sin_addr.s_addr = resolve(host);
  477.     fsock.sin_port = port;
  478.  
  479.     switch(cmd[0]){
  480.     case 'r':
  481.         data[0] = SYS_RESET;
  482.         if(key != NULLCHAR)
  483.             strncpy(&data[1],key,klen);
  484.         break;
  485.     case 'e':
  486.         data[0] = SYS_EXIT;
  487.         if(key != NULLCHAR)
  488.             strncpy(&data[1],key,klen);
  489.         break;
  490.     case 'k':
  491.         data[0] = KICK_ME;
  492.         if(addr != 0)
  493.             put32(&data[1],addr);
  494.         break;
  495.     default:
  496.         printf("Unknown command %s\n",cmd);
  497.         goto cleanup;
  498.     }
  499.     /* Form the command packet and send it */
  500.     if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
  501.         printf("sendto failed: %s\n",sys_errlist[errno]);
  502.         goto cleanup;
  503.     }
  504. cleanup:
  505.     if(data != &x)
  506.         free(data);
  507.     close_s(s);
  508.     return 0;
  509. }
  510.  
  511. /* Log messages of the form
  512.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  513.  */
  514. #if    defined(ANSIPROTO) && !defined(AMIGA)
  515. void
  516. log(int s,char *fmt, ...)
  517. {
  518.     va_list ap;
  519.     char *cp;
  520.     long t;
  521.     int fd,i;
  522.     struct sockaddr fsocket;
  523.  
  524.     if(Logfp == NULLFILE)
  525.         return;
  526.  
  527.     time(&t);
  528.     cp = ctime(&t);
  529.     rip(cp);
  530.     i = SOCKSIZE;
  531.     fprintf(Logfp,"%s",cp);
  532.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  533.         fprintf(Logfp," %s",psocket(&fsocket));
  534.  
  535.     fprintf(Logfp," - ");
  536.     va_start(ap,fmt);
  537.     vfprintf(Logfp,fmt,ap);
  538.     va_end(ap);
  539.     fprintf(Logfp,"\n");
  540.     fflush(Logfp);
  541. #ifdef    MSDOS
  542.     /* MS-DOS doesn't really flush files until they're closed */
  543.     fd = fileno(Logfp);
  544.     if((fd = dup(fd)) != -1)
  545.         close(fd);
  546. #endif
  547.  
  548. }
  549. #else
  550. /*VARARGS2*/
  551. void
  552. log(s,fmt,arg1,arg2,arg3,arg4,arg5)
  553. int s;
  554. char *fmt;
  555. int arg1,arg2,arg3,arg4,arg5;
  556. {
  557.     char *cp;
  558.     long t;
  559.     int fd,i;
  560.     struct sockaddr fsocket;
  561.  
  562.     if(Logfp == NULLFILE)
  563.         return;
  564.     time(&t);
  565.     cp = ctime(&t);
  566.     rip(cp);
  567.     i = SOCKSIZE;
  568.     fprintf(Logfp,"%s",cp);
  569.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  570.         fprintf(Logfp," %s",psocket(&fsocket));
  571.  
  572.     fprintf(Logfp," - ");
  573.     fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
  574.     fprintf(Logfp,"\n");
  575.     fflush(Logfp);
  576. #ifdef    MSDOS
  577.     /* MS-DOS doesn't really flush files until they're closed */
  578.     fd = fileno(Logfp);
  579.     if((fd = dup(fd)) != -1)
  580.         close(fd);
  581. #endif
  582. }
  583. #endif
  584.  
  585.